home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / dix / dixfonts.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-14  |  10.4 KB  |  430 lines

  1. /************************************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ************************************************************************/
  24.  
  25. /* $XConsortium: dixfonts.c,v 1.9 89/07/16 17:24:57 rws Exp $ */
  26.  
  27. #define NEED_REPLIES
  28. #include "X.h"
  29. #include "Xmd.h"
  30. #include "Xproto.h"
  31. #include "dixfontstr.h"
  32. #include "fontstruct.h"
  33. #include "scrnintstr.h"
  34. #include "resource.h"
  35. #include "dix.h"
  36. #include "cursorstr.h"
  37. #include "misc.h"
  38. #include "opaque.h"
  39.  
  40. #define QUERYCHARINFO(pci, pr)  *(pr) = (pci)->metrics
  41.  
  42. extern FontPtr     defaultFont;
  43.  
  44. /*
  45.  * adding RT_FONT prevents conflict with default cursor font
  46.  */
  47. Bool
  48. SetDefaultFont( defaultfontname)
  49.     char *    defaultfontname;
  50. {
  51.     FontPtr    pf;
  52.  
  53.    pf = OpenFont( (unsigned)strlen( defaultfontname), defaultfontname);
  54.     if (!pf || !AddResource(FakeClientID(0), RT_FONT, (pointer)pf))
  55.     return FALSE;
  56.     defaultFont = pf;
  57.     return TRUE;
  58. }
  59.  
  60. /*
  61.  * Check reference count first, load font only if necessary.
  62.  */
  63. FontPtr 
  64. OpenFont(lenfname, pfontname)
  65.     unsigned    lenfname;
  66.     char *    pfontname;
  67. {
  68.     FontPtr     pfont;
  69.     int        nscr;
  70.     ScreenPtr    pscr;
  71.  
  72.     pfont = FontFileLoad(pfontname, lenfname);
  73.  
  74.     if (pfont == NullFont)
  75.     {
  76. #ifdef notdef
  77.     ErrorF(  "OpenFont: read failed on file %s\n", ppathname);
  78. #endif
  79.     return NullFont;
  80.     }
  81.  
  82.     if (pfont->refcnt != 0) {
  83.     pfont->refcnt += 1;
  84.     return pfont;
  85.     }
  86.  
  87.     /*
  88.      * since this font has been newly read off disk, ask each screen to
  89.      * realize it.
  90.      */
  91.     pfont->refcnt = 1;
  92.     for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
  93.     {
  94.     pscr = screenInfo.screens[nscr];
  95.         if ( pscr->RealizeFont)
  96.         ( *pscr->RealizeFont)( pscr, pfont);
  97.     }
  98.     return pfont;
  99. }
  100.  
  101. /*
  102.  * Decrement font's ref count, and free storage if ref count equals zero
  103.  */
  104. /*ARGSUSED*/
  105. int
  106. CloseFont(pfont, fid)
  107.     FontPtr     pfont;
  108.     Font    fid;
  109. {
  110.     int        nscr;
  111.     ScreenPtr    pscr;
  112.  
  113.     if (pfont == NullFont)
  114.         return(Success);
  115.     if (--pfont->refcnt == 0)
  116.     {
  117.     /*
  118.      * since the last reference is gone, ask each screen to
  119.      * free any storage it may have allocated locally for it.
  120.      */
  121.     for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
  122.     {
  123.         pscr = screenInfo.screens[nscr];
  124.         if ( pscr->UnrealizeFont)
  125.         ( *pscr->UnrealizeFont)( pscr, pfont);
  126.     }
  127.     if (pfont == defaultFont)
  128.         defaultFont = NULL;
  129.     FontUnload(pfont);
  130.     }
  131.    return(Success);
  132. }
  133.  
  134. Bool
  135. DescribeFont(pfontname, lenfname, pfi, ppfp)
  136.     char *pfontname;
  137.     int lenfname;
  138.     FontInfoPtr pfi;
  139.     DIXFontPropPtr *ppfp;    /* return */
  140. {
  141.     FontPtr pfont;
  142.     Bool found;
  143.  
  144.     found = FontFilePropLoad(pfontname, (unsigned int)lenfname,
  145.                  &pfont, pfi, ppfp);
  146.  
  147.     if (!found)
  148.     return FALSE;
  149.     if (pfont != NullFont) {    /* need to get it myself */
  150.     *pfi = *pfont->pFI;
  151.     if (pfi->inkMetrics) {
  152.         pfi->minbounds = *pfont->pInkMin;
  153.         pfi->maxbounds = *pfont->pInkMax;
  154.     }
  155.     if (pfi->nProps != 0) {
  156.         *ppfp = (DIXFontPropPtr)xalloc(sizeof(DIXFontProp)*pfi->nProps);
  157.         if (*ppfp == NullDIXFontProp)
  158.         return FALSE;
  159.         bcopy((char *)pfont->pFP, (char *)*ppfp,
  160.           (int)(sizeof(DIXFontProp) * pfi->nProps));
  161.     }
  162.     }
  163.  
  164.     return TRUE;
  165. }
  166.  
  167. void
  168. QueryFont( pf, pr, nprotoxcistructs)
  169.     FontPtr         pf;
  170.     xQueryFontReply *    pr;    /* caller must allocate this storage */
  171.     int        nprotoxcistructs;
  172. {
  173.     FontInfoPtr     pfi = pf->pFI;
  174.     CharInfoPtr     pci;
  175.     DIXFontProp *    pfp;
  176.     int        ct;
  177.     xFontProp *    prfp;
  178.     xCharInfo *    prci;
  179.  
  180.     /* pr->length set in dispatch */
  181.     pr->minCharOrByte2 = pfi->firstCol;
  182.     pr->defaultChar = pfi->chDefault;
  183.     pr->maxCharOrByte2 = pfi->lastCol;
  184.     pr->drawDirection = pfi->drawDirection;
  185.     pr->allCharsExist = pfi->allExist;
  186.     pr->minByte1 = pfi->firstRow;
  187.     pr->maxByte1 = pfi->lastRow;
  188.     pr->fontAscent = pfi->fontAscent;
  189.     pr->fontDescent = pfi->fontDescent;
  190.  
  191.     QUERYCHARINFO( pf->pInkMin, &pr->minBounds); 
  192.     QUERYCHARINFO( pf->pInkMax, &pr->maxBounds); 
  193.  
  194.     pr->nFontProps = pfi->nProps; 
  195.     pr->nCharInfos = nprotoxcistructs; 
  196.  
  197.  
  198.     for ( ct=0,
  199.         pfp=pf->pFP,
  200.         prfp=(xFontProp *)(&pr[1]);
  201.       ct < pfi->nProps;
  202.       ct++, pfp++, prfp++)
  203.     {
  204.     prfp->name = pfp->name;
  205.     prfp->value = pfp->value;
  206.     }
  207.  
  208.     for ( ct=0,
  209.         pci = &pf->pInkCI[0],
  210.         prci=(xCharInfo *)(prfp);
  211.       ct<nprotoxcistructs;
  212.       ct++, pci++, prci++)
  213.     QUERYCHARINFO( pci, prci);
  214. }
  215.  
  216. void
  217. queryCharInfo( pci, pr)
  218.     CharInfoPtr         pci;
  219.     xCharInfo *        pr;    /* protocol packet to fill in */
  220. {
  221.     QUERYCHARINFO(pci, pr);
  222. }
  223.  
  224. /* text support routines. A charinfo array builder, and a bounding */
  225. /* box calculator */
  226.  
  227. void
  228. GetGlyphs(font, count, chars, fontEncoding, glyphcount, glyphs)
  229.     FontPtr font;
  230.     unsigned long count;
  231.     register unsigned char *chars;
  232.     FontEncoding fontEncoding;
  233.     unsigned long *glyphcount;    /* RETURN */
  234.     CharInfoPtr glyphs[];    /* RETURN */
  235. {
  236.     CharInfoPtr        pCI = font->pCI;
  237.     FontInfoPtr        pFI = font->pFI;
  238.     unsigned int    firstCol = pFI->firstCol;
  239.     unsigned int    numCols = pFI->lastCol - firstCol + 1;
  240.     unsigned int    firstRow = pFI->firstRow;
  241.     unsigned int    numRows = pFI->lastRow - firstRow + 1;
  242.     unsigned int    chDefault = pFI->chDefault;
  243.     unsigned int    cDef = chDefault - firstCol;
  244.     register unsigned long    i;
  245.     unsigned long        n;
  246.     register unsigned int    c;
  247.     register CharInfoPtr    ci;
  248.  
  249.     n = 0;
  250.     switch (fontEncoding) {
  251.  
  252.     case Linear8Bit:
  253.     case TwoD8Bit:
  254.         if (pFI->allExist && (cDef < numCols)) {
  255.         for (i=0; i < count; i++) {
  256.  
  257.             c = (*chars++) - firstCol;
  258.             if (c >= numCols) {
  259.             c = cDef;
  260.             }
  261.             ci = &pCI[c];
  262.             glyphs[i] = ci;
  263.         }
  264.         n = count;
  265.         } else {
  266.         for (i=0; i < count; i++) {
  267.     
  268.             c = (*chars++) - firstCol;
  269.             if (c < numCols) {
  270.             ci = &pCI[c];
  271.             if (ci->exists) {glyphs[n++] = ci; continue;}
  272.             }
  273.     
  274.             if (cDef < numCols) {
  275.             ci = &pCI[cDef];
  276.             if (ci->exists) glyphs[n++] = ci;
  277.             }
  278.         }
  279.         }
  280.         break;
  281.  
  282.     case Linear16Bit:
  283.         if (pFI->allExist && (cDef < numCols)) {
  284.         for (i=0; i < count; i++) {
  285.  
  286.             c = *chars++ << 8;
  287.             c = (c | *chars++) - firstCol;
  288.             if (c >= numCols) {
  289.             c = cDef;
  290.             }
  291.             ci = &pCI[c];
  292.             glyphs[i] = ci;
  293.         }
  294.         n = count;
  295.         } else {
  296.         for (i=0; i < count; i++) {
  297.     
  298.             c = *chars++ << 8;
  299.             c = (c | *chars++) - firstCol;
  300.             if (c < numCols) {
  301.             ci = &pCI[c];
  302.             if (ci->exists) {glyphs[n++] = ci; continue;}
  303.             }
  304.     
  305.             if (cDef < numCols) {
  306.             ci = &pCI[cDef];
  307.             if (ci->exists) glyphs[n++] = ci;
  308.             }
  309.         }
  310.         }
  311.         break;
  312.  
  313.     case TwoD16Bit:
  314.         for (i=0; i < count; i++) {
  315.         register unsigned int row;
  316.         register unsigned int col;
  317.  
  318.         row = (*chars++) - firstRow;
  319.         col = (*chars++) - firstCol;
  320.         if ((row < numRows) && (col < numCols)) {
  321.             c = row*numCols + col;
  322.             ci = &pCI[c];
  323.             if (ci->exists) {glyphs[n++] = ci; continue;}
  324.         }
  325.  
  326.         row = (chDefault >> 8)-firstRow;
  327.         col = (chDefault & 0xff)-firstCol;
  328.         if ((row < numRows) && (col < numCols)) {
  329.             c = row*numCols + col;
  330.             ci = &pCI[c];
  331.             if (ci->exists) glyphs[n++] = ci;
  332.         }
  333.         }
  334.         break;
  335.     }
  336.     *glyphcount = n;
  337. }
  338.  
  339.  
  340. void
  341. QueryGlyphExtents(font, charinfo, count, info)
  342.     FontPtr font;
  343.     CharInfoPtr *charinfo;
  344.     unsigned long count;
  345.     register ExtentInfoRec *info;
  346. {
  347.     register CharInfoPtr *ci = charinfo;
  348.     register unsigned long i;
  349.  
  350.     info->drawDirection = font->pFI->drawDirection;
  351.  
  352.     info->fontAscent = font->pFI->fontAscent;
  353.     info->fontDescent = font->pFI->fontDescent;
  354.  
  355.     if (count != 0) {
  356.  
  357.     info->overallAscent  = (*ci)->metrics.ascent;
  358.     info->overallDescent = (*ci)->metrics.descent;
  359.     info->overallLeft    = (*ci)->metrics.leftSideBearing;
  360.     info->overallRight   = (*ci)->metrics.rightSideBearing;
  361.     info->overallWidth   = (*ci)->metrics.characterWidth;
  362.  
  363.     if (font->pFI->constantMetrics && font->pFI->noOverlap) {
  364.         info->overallWidth *= count;
  365.         info->overallRight += (info->overallWidth -
  366.                    (*ci)->metrics.characterWidth);
  367.         return;
  368.     }
  369.     for (i = count, ci++; --i != 0; ci++) {
  370.         info->overallAscent = max(
  371.             info->overallAscent,
  372.         (*ci)->metrics.ascent);
  373.         info->overallDescent = max(
  374.             info->overallDescent,
  375.         (*ci)->metrics.descent);
  376.         info->overallLeft = min(
  377.         info->overallLeft,
  378.         info->overallWidth+(*ci)->metrics.leftSideBearing);
  379.         info->overallRight = max(
  380.         info->overallRight,
  381.         info->overallWidth+(*ci)->metrics.rightSideBearing);
  382.         /* yes, this order is correct; overallWidth IS incremented last */
  383.         info->overallWidth += (*ci)->metrics.characterWidth;
  384.     }
  385.  
  386.     } else {
  387.  
  388.     info->overallAscent  = 0;
  389.     info->overallDescent = 0;
  390.     info->overallWidth   = 0;
  391.     info->overallLeft    = 0;
  392.     info->overallRight   = 0;
  393.  
  394.     }
  395. }
  396.  
  397. Bool
  398. QueryTextExtents(font, count, chars, info)
  399.     FontPtr font;
  400.     unsigned long count;
  401.     unsigned char *chars;
  402.     ExtentInfoRec *info;
  403. {
  404.     CharInfoPtr *charinfo;
  405.     unsigned long n;
  406.     CharInfoPtr    oldCI;
  407.     Bool oldCM;
  408.  
  409.     charinfo = (CharInfoPtr *)ALLOCATE_LOCAL(count*sizeof(CharInfoPtr));
  410.     if(!charinfo)
  411.     return FALSE;
  412.     oldCI = font->pCI;
  413.     /* kludge, temporarily stuff in Ink metrics */
  414.     font->pCI = font->pInkCI;
  415.     if (font->pFI->lastRow == 0)
  416.     GetGlyphs(font, count, chars, Linear16Bit, &n, charinfo);
  417.     else
  418.     GetGlyphs(font, count, chars, TwoD16Bit, &n, charinfo);
  419.     /* restore real glyph metrics */
  420.     font->pCI = oldCI;
  421.     oldCM = font->pFI->constantMetrics;
  422.     /* kludge, ignore bitmap metric flag */
  423.     font->pFI->constantMetrics = FALSE;
  424.     QueryGlyphExtents(font, charinfo, n, info);
  425.     /* restore bitmap metric flag */
  426.     font->pFI->constantMetrics = oldCM;
  427.     DEALLOCATE_LOCAL(charinfo);
  428.     return TRUE;
  429. }
  430.